﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NetPE.Core.Metadata.Tables;
using NetPE.Core.Metadata.Heaps;
using NetPE.Dialogs;
using NetPE.Core.Metadata;
using NetPE.Core.Metadata.Methods;
using NetPE.Core;

namespace NetPE
{
    public partial class MdTablesEditor : BaseEditor
    {
        public MdTablesEditor()
        {
            InitializeComponent();
        }

        private void deleteToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            try
            {
                TreeNode row = treeView1.SelectedNode;
                TreeNode tbl = row.Parent;
                (tbl.Tag as MetadataTable).Rows.Remove(row.Tag as MetadataRow);
                tbl.Nodes.Remove(row);
            }
            catch
            {
                MessageBox.Show("Error!");
            }
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (Object as TablesHeap)[(treeView1.SelectedNode.Tag as MetadataTable).Type] = null;
        }

        private void addRowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (treeView1.SelectedNode.Tag as MetadataTable).Rows.Add(new MetadataRow(treeView1.SelectedNode.Tag as MetadataTable));
            RefreshData();
        }

        private void addTableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new NewTableDialog(this).ShowDialog();
            RefreshData();
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Tag is MetadataRow)
            {
                mdRowEditor1.Hide();
                mdRowEditor1.Object = e.Node.Tag;
                mdRowEditor1.Show();
            }
        }

        private void commitChangesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (Object as TablesHeap).Save();
        }

        protected override void RefreshData()
        {
            this.splitContainer1.SplitterDistance = 125;
            treeView1.Nodes.Clear();
            treeView1.ContextMenuStrip = root;
            mdRowEditor1.Hide();
            TablesHeap h = (Object as TablesHeap);
            for (int i = 0; i < 0x2d; i++)
            {
                if (h[(TableType)i] == null) continue;
                TreeNode tblN = new TreeNode(h[(TableType)i].Type.ToString()) { Tag = h[(TableType)i] };
                tblN.ContextMenuStrip = table;
                for (int ii = 1; ii <= h[(TableType)i].Rows.Count; ii++)
                {
                    TreeNode rowN = new TreeNode(ii.ToString("x").ToUpper()) { Tag = h[(TableType)i].Rows[ii] };
                    if ((TableType)i == TableType.MethodDef)
                    {
                        rowN.ContextMenuStrip = mtdRow;
                    }
                    else
                    {
                        rowN.ContextMenuStrip = row;
                    }
                    tblN.Nodes.Add(rowN);
                }
                treeView1.Nodes.Add(tblN);
            }
        }

        private void disassembleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                MetadataRow row = treeView1.SelectedNode.Tag as MetadataRow;
                MetadataRoot root = row.Container.Heap.Stream.Root;
                byte[] dat = root.Directory.Datas[(Rva)row["Rva"]].Data;
                if (((MethodImplAttributes)row["ImplFlags"] & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.IL)
                {
                    ManagedMethodBody bdy = new ManagedMethodBody(row);
                    bdy.Load(dat);
                    CilDisassembly dis = new CilDisassembly();
                    dis.Disassemble(bdy);
                    dis.ShowDialog();
                }
                else if (((MethodImplAttributes)row["ImplFlags"] & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Native)
                {
                    NativeMethodBody bdy = new NativeMethodBody(row);
                    bdy.Load(dat);
                    x86Disassembly dis = new x86Disassembly();
                    dis.Disassemble(bdy);
                    dis.ShowDialog();
                }
            }
            catch
            {
                MessageBox.Show("Error");
            }
        }
    }
}
